#include <QString>
#include <QDebug>

#include "simpletcpsocketdll.h"

SimpleTcpSocketDLL::SimpleTcpSocketDLL(){
    int loop_i = 0;
    this->TcpClientNumber = 0;
    for(loop_i= 0;loop_i<maxCLIENTNUMBER;loop_i++){
        this->pSimpleTcpClientInfo[loop_i] = nullptr;
        this->pTcpSocket[loop_i] = new QTcpSocket();
    }
}

SimpleTcpSocketDLL::~SimpleTcpSocketDLL(){
    int loop_i;
    for(loop_i= 0;loop_i<maxCLIENTNUMBER;loop_i++){
        if( this->pSimpleTcpClientInfo[loop_i] != nullptr){
            delete pSimpleTcpClientInfo[loop_i];
        }
        delete pTcpSocket[loop_i];
    }
}

short SimpleTcpSocketDLL::SimpleTcpClientadd(const QString ip, const int port, int &Order){
    if(this->TcpClientNumber != maxCLIENTNUMBER){
        this->pSimpleTcpClientInfo[TcpClientNumber] = new SimpleTcpClientInfo;
        this->pSimpleTcpClientInfo[TcpClientNumber]->IP = ip;
        this->pSimpleTcpClientInfo[TcpClientNumber]->Port = port;
        this->pSimpleTcpClientInfoMarkInit(TcpClientNumber);
        this->pSimpleTcpClientInfoSwitchInit(TcpClientNumber);
        Order = this->TcpClientNumber;
        this->TcpClientNumber = this->TcpClientNumber + 1;
        return 1;
    }
    else{
        return 2;
    }
    return 0;
}

short SimpleTcpSocketDLL::SimpleTcpClientconnect(const int Order){
    this->pSimpleTcpClientInfo[Order]->switch_connect = true;
    return 1;
}

short SimpleTcpSocketDLL::SimpleTcpClientDisconnect(const int Order){
    this->pSimpleTcpClientInfo[Order]->switch_disconnect = true;
    return 1;
}
short  SimpleTcpSocketDLL::SimpleTcpClientClose(const int Order){
    this->pSimpleTcpClientInfo[Order]->switch_close = true;
    return 1;
}
short SimpleTcpSocketDLL::SimpleTcpClientremove(const int Order){
    this->pSimpleTcpClientInfo[Order]->switch_remove = true;
    return 1;
}

short SimpleTcpSocketDLL::SimpleTcpClientWriteData(const int Order, QByteArray Data){
    this->pSimpleTcpClientInfo[Order]->SendData = Data;
    this->pSimpleTcpClientInfo[Order]->switch_send = true;
    this->pSimpleTcpClientInfo[Order]->mark_sendbusy = true;
    return 1;
}
short SimpleTcpSocketDLL::SimpleTcpClientReadData(const int Order, QByteArray& Data){
    Data = this->pSimpleTcpClientInfo[Order]->RecvData;
    this->pSimpleTcpClientInfo[Order]->mark_ready2read = false;
    return 1;
}
short SimpleTcpSocketDLL::SimpleTcpClientSendBusy(const int Order,bool& busy){
    if(pSimpleTcpClientInfo[Order] != nullptr && this->pSimpleTcpClientInfo[Order]->mark_connect == true){
        busy = this->pSimpleTcpClientInfo[Order]->mark_sendbusy;
    }
    return -1;
}

short SimpleTcpSocketDLL::SimpleTcpClientRead2Read(const int Order,bool& ready){
    if(pSimpleTcpClientInfo[Order] != nullptr && this->pSimpleTcpClientInfo[Order]->mark_connect == true){
        ready = this->pSimpleTcpClientInfo[Order]->mark_ready2read;
    }
    return -1;
}

bool  SimpleTcpSocketDLL::isTcpClientSendBusy(const int Order){
    if(pSimpleTcpClientInfo[Order] != nullptr && this->pSimpleTcpClientInfo[Order]->mark_connect == true){
        return  this->pSimpleTcpClientInfo[Order]->mark_sendbusy;
    }
    return -1;
}
bool  SimpleTcpSocketDLL::isTcpClientRead2Read(const int Order){
    if(pSimpleTcpClientInfo[Order] != nullptr && this->pSimpleTcpClientInfo[Order]->mark_connect == true){
        return  this->pSimpleTcpClientInfo[Order]->mark_sendbusy;
    }
    return -1;
}

short SimpleTcpSocketDLL::pSimpleTcpClientInfoMarkInit(int Order){

    this->pSimpleTcpClientInfo[Order]->mark_sendbusy = false;
    this->pSimpleTcpClientInfo[Order]->mark_readbusy = false;
    this->pSimpleTcpClientInfo[Order]->mark_ready2read = false;
    this->pSimpleTcpClientInfo[Order]->mark_connect = false;

    return 1;
}

short SimpleTcpSocketDLL::pSimpleTcpClientInfoSwitchInit(int Order){

    this->pSimpleTcpClientInfo[Order]->switch_connect = false;
    this->pSimpleTcpClientInfo[Order]->switch_disconnect = false;
    this->pSimpleTcpClientInfo[Order]->switch_remove = false;

    this->pSimpleTcpClientInfo[Order]->switch_close = false;
    this->pSimpleTcpClientInfo[Order]->switch_send = false;
    this->pSimpleTcpClientInfo[Order]->switch_receive = false;

    return 1;
}

bool SimpleTcpSocketDLL::isTcpClientConnectStatus(const int Order){
    return this->pSimpleTcpClientInfo[Order]->mark_connect;
}

void SimpleTcpSocketDLL::SimpleclientMainThreadLoopRun(short type){
    switch (type) {
        case 1:
            this->SimpleclientMainThreadLoopRun_StateChange();
            break;
        case 2:
            this->SimpleclientMainThreadLoopRun_Send();
            break;
        case 3:
            this->SimpleclientMainThreadLoopRun_Receive();
            break;
        default:
            break;
    }
}


void SimpleTcpSocketDLL::SimpleclientMainThreadLoopRun_StateChange(){
    int loop_i = 0;
    for(loop_i = 0; loop_i <= TcpClientNumber; loop_i++){
        if(pSimpleTcpClientInfo[loop_i] != nullptr){
            if(this->pSimpleTcpClientInfo[loop_i]->switch_connect == true){
                switch (pTcpSocket[loop_i]->state()) {
                case 0:
                    this->pTcpSocket[loop_i]->connectToHost(QHostAddress(this->pSimpleTcpClientInfo[loop_i]->IP),
                                                            this->pSimpleTcpClientInfo[loop_i]->Port);
                    break;
                default:
                    if (this->pTcpSocket[loop_i]->waitForConnected(1)){
                        this->pSimpleTcpClientInfo[loop_i]->mark_connect = true;
                        this->pSimpleTcpClientInfo[loop_i]->switch_connect = false;
                    }
                    break;
                }
            }

            if(this->pSimpleTcpClientInfo[loop_i]->mark_connect == true){
                if(this->pSimpleTcpClientInfo[loop_i]->switch_disconnect == true){
                    this->pTcpSocket[loop_i]->disconnectFromHost();
                    this->pSimpleTcpClientInfo[loop_i]->mark_connect = false;
                    this->pSimpleTcpClientInfo[loop_i]->switch_disconnect = false;
                }
                if(this->pSimpleTcpClientInfo[loop_i]->switch_remove == true){
                    if(pSimpleTcpClientInfo[loop_i] != nullptr){
                        delete pSimpleTcpClientInfo[loop_i];
                    }
                }
            }
        }
    }
}

void SimpleTcpSocketDLL::SimpleclientMainThreadLoopRun_Send(){
    int loop_i = 0;
    for(loop_i = 0; loop_i <= TcpClientNumber; loop_i++){
        if(pSimpleTcpClientInfo[loop_i] != nullptr &&
           pSimpleTcpClientInfo[loop_i]->mark_connect == true &&
           pSimpleTcpClientInfo[loop_i]->switch_send == true){
            this->pTcpSocket[loop_i]->write(pSimpleTcpClientInfo[loop_i]->SendData);
            if(this->pTcpSocket[loop_i]->waitForBytesWritten(1)){
                this->pSimpleTcpClientInfo[loop_i]->switch_send = false;
                this->pSimpleTcpClientInfo[loop_i]->mark_sendbusy = false;
                this->pSimpleTcpClientInfo[loop_i]->mark_readbusy = true;
                this->pTcpSocket[loop_i]->flush();
            }
        }
    }
}

void SimpleTcpSocketDLL::SimpleclientMainThreadLoopRun_Receive(){
    int loop_i = 0;
    for(loop_i = 0; loop_i <= TcpClientNumber; loop_i++){
        if(pSimpleTcpClientInfo[loop_i] != nullptr &&
           pSimpleTcpClientInfo[loop_i]->mark_connect == true &&
           pSimpleTcpClientInfo[loop_i]->mark_readbusy == true){
            if(this->pTcpSocket[loop_i]->waitForReadyRead(1) == true){
                this->pSimpleTcpClientInfo[loop_i]->RecvData = this->pTcpSocket[loop_i]->readAll();
                this->pSimpleTcpClientInfo[loop_i]->mark_ready2read = true;
                this->pSimpleTcpClientInfo[loop_i]->mark_readbusy = false;
            }
        }
    }
}

